package com.sky.aspect;

import com.sky.anno.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Slf4j
@Component
@Aspect
public class AutoFillAspect {
    @Before("@annotation(com.sky.anno.AutoFill)")
    public void autoFill(JoinPoint jpoint) {//joinpoint可以获取所要执行的方法名、参数等信息
        log.info("执行公共字段自动填充");
        //获取目标方法上的注解并拿到注解里的属性值
        MethodSignature methodSignature = (MethodSignature) jpoint.getSignature();//获取方法签名
        Method method = methodSignature.getMethod();//获取方法对象
        AutoFill autoFill = method.getAnnotation(AutoFill.class);//获取注解对象
        OperationType operationType = autoFill.value();//获取注解里的属性值
        //获取目标方法的参考对象
        Object[] args = jpoint.getArgs();
        if (args.length < 0&&args==null)
        {return;}
        Object entity = args[0];//获取第一个参数，即实体对象
        //判断注解中的属性值，如果是insert，则自动填充（创建时间，更新时间，创建者，更新者）
        try {
            if (operationType == OperationType.INSERT) {
            // 通过反射去补充属性值
            log.info("执行插入操作，自动填充公共字段");
            Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
            setCreateTime.invoke(entity, LocalDateTime.now());
            log.info("执行插入操作，自动填充公共字段，创建时间：" + LocalDateTime.now());
            Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            setUpdateTime.invoke(entity, LocalDateTime.now());
            log.info("执行插入操作，自动填充公共字段，更新时间：" + LocalDateTime.now());
            Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
            setCreateUser.invoke(entity, BaseContext.getCurrentId()); // TODO: 需要从当前登录用户中获取
            log.info("执行插入操作，自动填充公共字段，创建者：" + BaseContext.getCurrentId());
            Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
            setUpdateUser.invoke(entity, BaseContext.getCurrentId()); // TODO: 需要从当前登录用户中获取
            log.info("执行插入操作，自动填充公共字段，更新者：" + BaseContext.getCurrentId());
            }

            else if (operationType == OperationType.UPDATE) {
            Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
            setUpdateTime.invoke(entity, LocalDateTime.now());
            log.info("执行更新操作，自动填充公共字段，更新时间：" + LocalDateTime.now());
            Method setUpdateUser = entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);
            setUpdateUser.invoke(entity, BaseContext.getCurrentId()); // TODO: 需要从当前登录用户中获取
            log.info("执行更新操作，自动填充公共字段，更新者：" + BaseContext.getCurrentId());
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        //判断注解中的属性值，如果是update，则自动填充（更新时间，更新者）
    }
}
